home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Compendium Deluxe 2
/
LSD and 17bit Compendium Deluxe - Volume II.iso
/
a
/
prog
/
misc
/
frefs11.lha
/
FetchRefs
/
Source
/
GenerateIndex
/
Lists.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-21
|
21KB
|
780 lines
/**************************************************************************/
/* Lists.c - all that's got to do with the lists, including building and */
/* I/O. */
/**************************************************************************/
#include "GenerateIndex.h"
struct Prefs Settings;
UBYTE DataName[108];
/// LoadData(STRPTR filename)
void
LoadData(STRPTR name)
{
STRPTR filename;
struct Node node;
FILE *file;
struct List *currentfile;
filename = name;
if (!name)
{
if (rtFileRequest(DataFileReq, DataName,
"Load file...",
TAG_END))
filename = JoinPath(DataFileReq->Dir, DataName);
if (!filename)
return;
}
if (file = fopen(filename, "r"))
{
while (fread(&node, sizeof(struct Node), 1, file) > 0)
{
if (node.ln_Type == 1)
{
struct FileEntry *entry;
if (entry = AllocVec((LONG)node.ln_Succ, MEMF_CLEAR))
{
entry->node.ln_Type = node.ln_Type;
entry->node.ln_Name = entry->Name;
fread(entry->afternode, ((LONG)node.ln_Succ) - sizeof(struct Node), 1, file);
NewList(currentfile = &entry->RefsList);
AddTail(&FileList, &entry->node);
} else
fseek(file, ((LONG)node.ln_Succ) - sizeof(struct Node), SEEK_CUR);
} else if (node.ln_Type == 2)
{
struct RefsEntry *entry;
if (entry = AllocVec((LONG)node.ln_Succ, MEMF_CLEAR))
{
entry->node.ln_Type = node.ln_Type;
entry->node.ln_Name = entry->Name;
fread(entry->afternode, ((LONG)node.ln_Succ) - sizeof(struct Node), 1, file);
AddTail(currentfile, &entry->node);
} else
fseek(file, ((LONG)node.ln_Succ) - sizeof(struct Node), SEEK_CUR);
}
}
fclose(file);
}
if (!name)
FreeVec(filename);
}
///
/// SaveData(STRPTR filename)
void
SaveData(STRPTR name)
{
STRPTR filename;
struct FileEntry *entry;
struct RefsEntry *refentry;
FILE *file;
void *copy;
filename = name;
if (!name)
{
if (rtFileRequest(DataFileReq, DataName,
"Save as...",
RTFI_Flags, FREQF_SAVE,
TAG_END))
filename = JoinPath(DataFileReq->Dir, DataName);
if (!filename)
return;
}
entry = (struct FileEntry *)FileList.lh_Head;
if (file = fopen(filename, "w"))
{
void *buf;
/* Bigger buffer gives faster I/O */
if (buf = AllocVec(10 * 1024, NULL))
setvbuf(file, buf, _IOFBF, 10 * 1024);
while (entry->node.ln_Succ)
{
int size;
copy = entry->node.ln_Succ;
size = ((sizeof(struct FileEntry) + strlen(entry->node.ln_Name) + 1) + 1) & ~1;
entry->node.ln_Succ = (void *)size;
fwrite(entry, 1, size, file);
entry->node.ln_Succ = copy;
refentry = entry->RefsList.lh_Head;
while (refentry->node.ln_Succ)
{
copy = refentry->node.ln_Succ;
size = ((sizeof(struct RefsEntry) + strlen(refentry->node.ln_Name) + 1) + 1) & ~1;
refentry->node.ln_Succ = (void *)size;
fwrite(refentry, 1, size, file);
refentry->node.ln_Succ = copy;
refentry = refentry->node.ln_Succ;
}
entry = entry->node.ln_Succ;
}
fclose(file);
FreeVec(buf);
}
if (!name)
FreeVec(filename);
}
///
/// IndexFileList(UBYTE *path, struct rtFileList *lst)
LONG
IndexFileList(UBYTE *path, struct rtFileList *lst)
{
UBYTE *dir;
if (!(dir = FullName(path)))
return(ERROR_NO_FREE_STORE);
do
{
if (lst->StrLen == -1)
IndexRecursive(dir, lst->Name);
else
IndexFile(dir, lst->Name);
} while (lst = lst->Next);
FreeVec(dir);
}
///
/// IndexRecursive(UBYTE *path, UBYTE *dir)
void
IndexRecursive(UBYTE *path, UBYTE *dir)
{
BPTR lock;
UBYTE *name;
struct FileInfoBlock *fib;
fib = AllocDosObject(DOS_FIB, NULL);
name = JoinPath(path, dir);
lock = Lock(name, ACCESS_READ);
Examine(lock, fib);
while (ExNext(lock, fib))
{
if (fib->fib_DirEntryType < 0)
IndexFile(name, fib->fib_FileName);
else if (Settings.Recursively)
IndexRecursive(name, fib->fib_FileName);
}
UnLock(lock);
FreeVec(name);
FreeDosObject(DOS_FIB, fib);
}
///
/// IndexFile(UBYTE *dir, UBYTE *filename)
void
IndexFile(UBYTE *dir, UBYTE *filename)
{
UBYTE *name;
if (name = JoinPath(dir, filename))
{
switch (FileType(name))
{
case FILE_AUTODOC: ADocToList(name); break;
case FILE_C: CToList(name); break;
case FILE_E: EToList(name); break;
case FILE_ASM: AsmToList(name); break;
}
FreeVec(name);
}
}
///
/// FileType(STRPTR filename)
LONG FileType(STRPTR filename)
{
BPTR file;
STRPTR buf;
LONG type = FILE_UNKNOWN;
if (buf = AllocVec(2048, NULL))
{
if (file = Open(filename, MODE_OLDFILE))
{
LONG len;
len = Read(file, buf, 2047);
Close(file);
if (len > 0)
{
buf[len] = 0;
if (strstr(buf, "TABLE OF CONTENTS"))
type = FILE_AUTODOC;
else if (strstr(buf, "#if"))
type = FILE_C;
else if (strstr(buf, "#define"))
type = FILE_C;
else if (strstr(buf, "\n(---) OBJECT"))
type = FILE_E;
else if (strstr(buf, "\nCONST"))
type = FILE_E;
else if (strstr(buf, "\nPROC"))
type = FILE_E;
else if (strstr(buf, "IFND"))
type = FILE_ASM;
else if (strstr(buf, "EQU"))
type = FILE_ASM;
else if (strstr(buf, "STRUCTURE"))
type = FILE_ASM;
else if (strstr(buf, "MACRO"))
type = FILE_ASM;
else if (strstr(buf, "BITDEF"))
type = FILE_ASM;
else
type = (Settings.UnknownFiles == UNKNOWN_ARE_AUTODOCS) ? FILE_AUTODOC : FILE_UNKNOWN;
}
}
FreeVec(buf);
}
return(type);
}
///
/// FullName(STRPTR path)
STRPTR
FullName(STRPTR path)
{
UBYTE *dir;
dir = path;
while (*dir)
if (*dir++ == ':')
{
if (dir = AllocVec(strlen(path) + 1, NULL))
strcpy(dir, path);
return(dir);
}
if (dir = AllocVec(512, NULL))
{
BPTR lok;
if (lok = Lock(path, ACCESS_READ))
{
NameFromLock(lok, dir, 512);
UnLock(lok);
}
}
return(dir);
}
///
/// JoinPath(UBYTE *dir, UBYTE *name)
UBYTE *
JoinPath(UBYTE *dir, UBYTE *name)
{
LONG len;
UBYTE *both;
len = strlen(dir) + 1 + strlen(name) + 1;
if (both = AllocVec(len, NULL))
{
strcpy(both, dir);
if (name[0])
AddPart(both, name, len);
}
return(both);
}
///
/// ADocToList(UBYTE *filename)
void
ADocToList(UBYTE *filename)
{
FILE *file;
UBYTE buf[256];
struct FileEntry *list;
LONG nextff = 0;
if (!Settings.AutoDocPrf.Active)
return;
if (!(list = AddFileToList(filename)))
return;
if (file = fopen(filename, "r"))
{
while (fgets(buf, 256, file))
{
STRPTR left, right;
LONG buflen = strlen(buf), rightlen = 0;
/* Always know where the next "reference ends" mark is */
if (ftell(file) > nextff)
{
LONG ch, wasat = ftell(file);
for (ch = 0; ch != '\f' && ch != EOF; ch = getc(file))
;
nextff = ftell(file) - 1;
fseek(file, wasat, SEEK_SET);
}
/* Skip formfeeds and remove trailing '\n' */
for (left = buf; *left == '\f'; left++) ;
buf[buflen - 1] = ' ';
/* Set 'right' to point to the start of the last word of the line */
right = buf + buflen;
while ((right[-1] == ' ') || (right[-1] == '\t'))
*--right = 0;
while ((right[-1] != ' ') && (right[-1] != '\t'))
right--, rightlen++;
/* Only one word on this line? */
if (right <= left)
continue;
/* Did the line start and end with two words that are alike? */
if (strncmp(left, right, rightlen) == 0)
{
LONG start = ftell(file) - buflen + (left - buf);
/* Set 'right' to point to the start of the name */
right = buf + strlen(buf);
while (IsAlphaNum(right[-1]))
right--;
AddRefToList(list, start, nextff - start, 0, right);
}
}
fclose(file);
}
if ((!Settings.KeepEmpty) && IsListEmpty(&list->RefsList))
{
Remove(&list->node);
FreeVec(list);
}
}
///
/// CToList(UBYTE *filename)
void
CToList(UBYTE *filename)
{
FILE *file;
struct FileEntry *list;
UBYTE buf[256], structname[128], namecopy[128], *c;
LONG lastlastend = 0, lastend = 0, offset = 0;
LONG lineoffset = 0, lastlineoffset = 0, totallines = 0;
BYTE inastruct = FALSE;
if (!Settings.CPrf.Active)
return;
if (!(list = AddFileToList(filename)))
return;
if ((Settings.CPrf.Define || Settings.CPrf.Struct || Settings.CPrf.Typedef) && (file = fopen(filename, "r")))
{
namecopy[0] = 0;
while (fgets(buf, 256, file) != NULL)
{
lineoffset++;
totallines++;
if (Settings.CPrf.Struct)
{
if ((c = strstr(buf, "struct")) || (c = strstr(buf, "union")))
{
c += (*c == 's') ? 6 : 5; /* Skip past keyword */
c = SetSName(structname, c);
/* Find '{' */ /*}*/
{
while (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\f')
c++;
/* Search forward if it's not on the current line */
if (*c == 0) {
short ch = ' ';
LONG savpos = ftell(file);
while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f')
ch = getc(file);
c[0] = ch;
fseek(file, savpos, SEEK_SET);
}
}
/* If an actual definition was found */
if (*c == '{' && structname[0])
{
inastruct = TRUE;
/* Now we can write the last one */
if (namecopy[0])
{
AddRefToList(list, lastlastend, offset - lastlastend, lastlineoffset, namecopy);
lastlastend = lastend;
}
strcpy(namecopy, structname);
lastlineoffset = lineoffset;
}
}
offset = ftell(file);
/* Reached the end of a definition */
if (inastruct && strstr(buf, "}"))
{
inastruct = FALSE;
lastend = offset;
lineoffset = 0;
}
}
if (Settings.CPrf.Define)
{
if (c = strstr(buf, "#define"))
{
SetSName(structname, c + 7);
AddRefToList(list, 0, -1, totallines, structname);
}
}
if (Settings.CPrf.Typedef)
{
if (c = strstr(buf, "typedef"))
{
while (*c != ';')
c++;
c--;
while (IsAlphaNum(*c))
c--;
c++;
SetSName(structname, c);
AddRefToList(list, 0, -1, totallines, structname);
}
}
}
/* Write the final one */
if (namecopy[0])
AddRefToList(list, lastlastend, offset - lastlastend, lastlineoffset, namecopy);
fclose(file);
}
if ((!Settings.KeepEmpty) && IsListEmpty(&list->RefsList))
{
Remove(&list->node);
FreeVec(list);
}
}
///
/// EToList(STRPTR filename)
void
EToList(STRPTR filename)
{
FILE *file;
struct FileEntry *list;
UBYTE buf[256], objectname[128], *c;
ULONG totallines = 0;
if (!Settings.EPrf.Active)
return;
if (!(list = AddFileToList(filename)))
return;
if ((Settings.EPrf.Const || Settings.EPrf.Object || Settings.EPrf.Proc) && (file = fopen(filename, "r")))
{
while (fgets(buf, 256, file) != NULL)
{
ULONG offset = ftell(file) - strlen(buf);
totallines++;
if (Settings.EPrf.Object)
{
if (c = strstr(buf, "OBJECT"))
{
c = SetSName(objectname, c + 6);
totallines++;
while (fgets(buf, 256, file) && (!strstr(buf, "ENDOBJECT")))
totallines++;
AddRefToList(list, offset, ftell(file) - offset, 0, objectname);
}
}
if (Settings.EPrf.Const)
{
if ((strncmp(buf, "CONST", 5)) == 0)
{
do
{
SetSName(objectname, buf + 5);
AddRefToList(list, offset, ftell(file) - offset, totallines, objectname);
totallines++;
if (!fgets(buf, 256, file))
break;
} while (strncmp(buf, " ", 5) == 0);
}
}
if (Settings.EPrf.Proc)
{
if ((strncmp(buf, "PROC", 4)) == 0)
{
SetSName(objectname, buf + 4);
AddRefToList(list, offset, strlen(buf), 0, objectname);
}
}
}
fclose(file);
}
if ((!Settings.KeepEmpty) && IsListEmpty(&list->RefsList))
{
Remove(&list->node);
FreeVec(list);
}
}
///
/// AsmToList(STRPTR filename)
void
AsmToList(STRPTR filename)
{
FILE *file;
struct FileEntry *list;
UBYTE buf[256], name[128], *c;
ULONG totallines = 0;
if (!Settings.AsmPrf.Active)
return;
if (!(list = AddFileToList(filename)))
return;
if ((Settings.AsmPrf.Equ || Settings.AsmPrf.Structure || Settings.AsmPrf.Macro) && (file = fopen(filename, "r")))
{
while (fgets(buf, 256, file))
{
ULONG offset = ftell(file) - strlen(buf);
STRPTR comment = buf;
/* Check for comment and skip rest of line */
while (*comment)
if ((*comment == ';') || (*comment == '*'))
*comment = 0;
else
comment++;
totallines++;
if (Settings.AsmPrf.Equ)
{
if ((c = strstr(buf, "EQU")) || (c = strstr(buf, "equ")))
{
c--;
while (*c == ' ' || *c == '\t')
c--;
while (IsAlphaNum(*c))
c--;
/* If the name starts with backslash (92) it's probably
* part of a macro and we ignore.
*/
if (*c != 92)
{
c++;
SetSName(name, c);
AddRefToList(list, 0, -1, totallines, name);
}
}
if (c = strstr(buf, "BITDEF"))
{
UBYTE mprefix[32], mname[32], mfinal[65];
ULONG i;
c += 6;
while (*c == ' ' || *c == '\t')
c++;
for (i = 0; IsAlphaNum(*c); c++, i++)
mprefix[i] = *c;
mprefix[i] = 0;
while (!IsAlphaNum(*c))
c++;
for (i = 0; IsAlphaNum(*c); c++, i++)
mname[i] = *c;
mname[i] = 0;
strcpy(mfinal, mprefix);
strcat(mfinal, "B_");
strcat(mfinal, mname);
AddRefToList(list, 0, -1, totallines, mfinal);
strcpy(mfinal, mprefix);
strcat(mfinal, "F_");
strcat(mfinal, mname);
AddRefToList(list, 0, -1, totallines, mfinal);
}
}
if (Settings.AsmPrf.Structure)
{
if (c = strstr(buf, "STRUCTURE"))
{
SetSName(name, c + 9);
AddRefToList(list, 0, -1, totallines, name);
}
}
if (Settings.AsmPrf.Macro)
{
if (c = strstr(buf, "MACRO"))
{
c--;
while (*c == ' ' || *c == '\t')
c--;
if (*c == ':')
c--;
while (IsAlphaNum(*c))
c--;
c++;
SetSName(name, c);
AddRefToList(list, 0, -1, totallines, name);
}
}
}
fclose(file);
}
if ((!Settings.KeepEmpty) && IsListEmpty(&list->RefsList))
{
Remove(&list->node);
FreeVec(list);
}
}
///
/// SetSName(UBYTE *buf, UBYTE *ptr)
UBYTE *
SetSName(UBYTE *buf, UBYTE *ptr)
{
while (*ptr == ' ' || *ptr == '\t')
++ptr;
while (IsAlphaNum(*ptr))
*buf++ = *ptr++;
*buf = 0;
return(ptr);
}
///
/// IsAlphaNum(UBYTE c)
BOOL
IsAlphaNum(UBYTE c)
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || (c == '_'))
return(1);
return(0);
}
///
/// AddFileToList(UBYTE *name)
struct FileEntry *
AddFileToList(UBYTE *name)
{
struct FileEntry *entry;
if (entry = AllocVec(sizeof(struct FileEntry) + strlen(name) + 1, NULL))
{
strcpy(entry->Name, name);
entry->node.ln_Name = entry->Name;
entry->node.ln_Type = 1;
NewList(&entry->RefsList);
AddTail(&FileList, &entry->node);
}
return(entry);
}
///
/// AddRefToList(struct FileEntry *, LONG offset, length, gotoline, STRPTR name)
struct RefsEntry *
AddRefToList(struct FileEntry *fileentry, LONG offset, LONG length, WORD gotoline, STRPTR name)
{
struct RefsEntry *entry;
/* Do not add the reference if the name is empty (ie ""). */
if (!name[0])
return(NULL);
if (entry = AllocVec(sizeof(struct RefsEntry) + strlen(name) + 1, NULL))
{
entry->Offset = offset;
entry->Length = length;
entry->Goto = gotoline;
strcpy(entry->Name, name);
entry->node.ln_Name = entry->Name;
entry->node.ln_Type = 2;
AddTail(&fileentry->RefsList, &entry->node);
}
return(entry);
}
///
/// ClearFileList()
void
ClearFileList(void)
{
struct FileEntry *freefile;
struct RefsEntry *freelist;
while (freefile = (struct FileEntry *)RemHead(&FileList))
{
while (freelist = (struct RefsEntry *)RemHead(&freefile->RefsList))
FreeVec(freelist);
FreeVec(freefile);
}
}
///